<!DOCTYPE html>
<html>
<!--
Copyright 2009 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<head>
  <title>Google Earth API Samples - Getting Viewport Globe Bounds</title>
  <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
  <!-- You should probably remove most of this extra cruft if you're copying
       this sample! -->
  <style type="text/css">@import "static/examples.css";</style>
  <style type="text/css">@import "static/prettify/prettify.css";</style>
  <script type="text/javascript" src="static/prettify/prettify.js"></script>
  
  <!-- Change the key below to your own Maps API key -->
  <script type="text/javascript" src="http://www.google.com/jsapi?hl=en&amp;key=ABQIAAAAwbkbZLyhsmTCWXbTcjbgbRSzHs7K5SvaUdm8ua-Xxy_-2dYwMxQMhnagaawTo7L1FE1-amhuQxIlXw"></script>
  <script type="text/javascript">
  /* <![CDATA[ */
  var ge;
  var map = null;
  
  google.load("earth", "1");
  google.load("maps", "2");

  function init() {
    google.earth.createInstance('map3d', initCB, failureCB);
    map = new GMap2(document.getElementById('map'));
    map.setCenter(new GLatLng(0, 0), 0);
    
  }
  
  function initCB(instance) {
    ge = instance;
    ge.getWindow().setVisibility(true);
    
    // add a navigation control
    ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO);
    
    // add some layers
    ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true);
    ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, true);

    var la = ge.createLookAt('');
    la.set(37, -122, 0, ge.ALTITUDE_RELATIVE_TO_GROUND, 0 , 0, 100000);
    ge.getView().setAbstractView(la);
    // just for comparison
    ge.getOptions().setOverviewMapVisibility(true);
    
    google.earth.addEventListener(ge.getView(), 'viewchange', function(evt) {
      map.clearOverlays();
      
      var totalBounds = new GLatLngBounds();
      
      // get the globe bounds (method 1)
      var globeBounds = ge.getView().getViewportGlobeBounds();
      var fakeBoundsCenter = null;
      
      if (globeBounds) {
        globeBounds.setNorth(Math.min(globeBounds.getNorth(), 85));
        globeBounds.setSouth(Math.max(globeBounds.getSouth(), -85));
        
        if (globeBounds.getEast() == 180 && globeBounds.getWest() == -180) {
          fakeBoundsCenter = new GLatLng(0, 0);
          var globeBoundsPolygon = new GPolygon([
              new GLatLng(globeBounds.getNorth(), -179),
              new GLatLng(globeBounds.getNorth(), 0),
              new GLatLng(globeBounds.getNorth(), 179),
              new GLatLng(globeBounds.getSouth(), 179),
              new GLatLng(globeBounds.getSouth(), 0),
              new GLatLng(globeBounds.getSouth(), -179),
              new GLatLng(globeBounds.getNorth(), -179)],
              '#0000ff', 2, 1.00,
              '#0000ff',    0.25,
              { clickable: false });
        } else {
          var globeBoundsPolygon = new GPolygon([
              new GLatLng(globeBounds.getNorth(), globeBounds.getWest()),
              new GLatLng(globeBounds.getNorth(), globeBounds.getEast()),
              new GLatLng(globeBounds.getSouth(), globeBounds.getEast()),
              new GLatLng(globeBounds.getSouth(), globeBounds.getWest()),
              new GLatLng(globeBounds.getNorth(), globeBounds.getWest())],
              '#0000ff', 2, 1.00,
              '#0000ff',    0.25,
              { clickable: false });
        }
        
        map.addOverlay(globeBoundsPolygon);
        
        var polyBounds = globeBoundsPolygon.getBounds();
        totalBounds.extend(polyBounds.getNorthEast());
        totalBounds.extend(polyBounds.getSouthWest());
      }
      
      // hit test the corners (method 2)
      var hitTestTL = ge.getView().hitTest(0, ge.UNITS_FRACTION, 0, ge.UNITS_FRACTION, ge.HIT_TEST_GLOBE);
      var hitTestTR = ge.getView().hitTest(1, ge.UNITS_FRACTION, 0, ge.UNITS_FRACTION, ge.HIT_TEST_GLOBE);
      var hitTestBR = ge.getView().hitTest(1, ge.UNITS_FRACTION, 1, ge.UNITS_FRACTION, ge.HIT_TEST_GLOBE);
      var hitTestBL = ge.getView().hitTest(0, ge.UNITS_FRACTION, 1, ge.UNITS_FRACTION, ge.HIT_TEST_GLOBE);
      
      // ensure that all hit tests succeeded (i.e. the viewport is 2d-mappable)
      if (hitTestTL && hitTestTR && hitTestBL && hitTestBR) {
        var hitTestBoundsPolygon = new GPolygon([
            new GLatLng(hitTestTL.getLatitude(), hitTestTL.getLongitude()),
            new GLatLng(hitTestTR.getLatitude(), hitTestTR.getLongitude()),
            new GLatLng(hitTestBR.getLatitude(), hitTestBR.getLongitude()),
            new GLatLng(hitTestBL.getLatitude(), hitTestBL.getLongitude()),
            new GLatLng(hitTestTL.getLatitude(), hitTestTL.getLongitude())],
            '#ff0000', 2, 1.00,
            '#ff0000',    0.25,
            { clickable: false });
        map.addOverlay(hitTestBoundsPolygon);
    
        var polyBounds = hitTestBoundsPolygon.getBounds();
        totalBounds.extend(polyBounds.getNorthEast());
        totalBounds.extend(polyBounds.getSouthWest());
      }
      
      if (!totalBounds.isEmpty()) {
        map.setCenter(fakeBoundsCenter ? fakeBoundsCenter : totalBounds.getCenter(),
            map.getBoundsZoomLevel(totalBounds));
      }
    });
    
    
    document.getElementById('installed-plugin-version').innerHTML =
      ge.getPluginVersion().toString();
  }
  
  function failureCB(errorCode) {
  }
  
  /* ]]> */
  </script>
</head>
<body onload="if(window.prettyPrint)prettyPrint();init();">
  <h1>Google Earth API Samples - Getting Viewport Globe Bounds</h1>
  <dl>
            <dt>Last Modified:</dt><dd>06/08/2009</dd>
    <dt>Installed Plugin Version:</dt><dd id="installed-plugin-version">...</dd>
  </dl>
  <div style="clear: both;"></div>
  
  <div id="ui" style="position: relative;">
    <div id="map3d" style="border: 1px solid silver; width: 500px; height: 500px;"></div>

    <div id="extra-ui" style="position: absolute; left: 520px; top: 0;">
      <span style="color: #00f">Bounding Box via getViewportGlobeBounds()</span><br/>
      <span style="color: #f00">Bounding Box via hitTest()<br/>
      &nbsp;&nbsp;&nbsp;<small>Note: if either of the four plugin corners return a null hitTest, the red polygon won't appear.</small></span><br/>
      <div id="map" style="width: 250px; height: 250px;"></div>
      
      <h2>Relevant Resources:</h2>
      <ul>
<li><a href="http://code.google.com/apis/earth/documentation/reference/interface_g_e_view.html">GEView Reference</a></li>
<li><a href="http://code.google.com/apis/earth/documentation/reference/google_earth_namespace.html">google.earth Namespace Reference</a></li>
<li><a href="http://code.google.com/apis/earth/documentation/reference/interface_kml_event.html">KmlEvent Reference</a></li>
<li><a href="http://code.google.com/apis/maps/documentation/reference.html#GPolygon">Maps API GPolygon Reference</a></li>
<a id="playground-button" href="http://code.google.com/apis/ajax/playground/?exp=earth#getting_viewport_globe_bounds"><img src="static/playground-button.png"/></a>      </ul>
      <h2>Relevant Code Excerpt:</h2>      <pre class="prettyprint lang-js">// just for comparison
ge.getOptions().setOverviewMapVisibility(true);

google.earth.addEventListener(ge.getView(), 'viewchange', function(evt) {
  map.clearOverlays();
  
  var totalBounds = new GLatLngBounds();
  
  // get the globe bounds (method 1)
  var globeBounds = ge.getView().getViewportGlobeBounds();
  var fakeBoundsCenter = null;
  
  if (globeBounds) {
    globeBounds.setNorth(Math.min(globeBounds.getNorth(), 85));
    globeBounds.setSouth(Math.max(globeBounds.getSouth(), -85));
    
    if (globeBounds.getEast() == 180 &amp;&amp; globeBounds.getWest() == -180) {
      fakeBoundsCenter = new GLatLng(0, 0);
      var globeBoundsPolygon = new GPolygon([
          new GLatLng(globeBounds.getNorth(), -179),
          new GLatLng(globeBounds.getNorth(), 0),
          new GLatLng(globeBounds.getNorth(), 179),
          new GLatLng(globeBounds.getSouth(), 179),
          new GLatLng(globeBounds.getSouth(), 0),
          new GLatLng(globeBounds.getSouth(), -179),
          new GLatLng(globeBounds.getNorth(), -179)],
          '#0000ff', 2, 1.00,
          '#0000ff',    0.25,
          { clickable: false });
    } else {
      var globeBoundsPolygon = new GPolygon([
          new GLatLng(globeBounds.getNorth(), globeBounds.getWest()),
          new GLatLng(globeBounds.getNorth(), globeBounds.getEast()),
          new GLatLng(globeBounds.getSouth(), globeBounds.getEast()),
          new GLatLng(globeBounds.getSouth(), globeBounds.getWest()),
          new GLatLng(globeBounds.getNorth(), globeBounds.getWest())],
          '#0000ff', 2, 1.00,
          '#0000ff',    0.25,
          { clickable: false });
    }
    
    map.addOverlay(globeBoundsPolygon);
    
    var polyBounds = globeBoundsPolygon.getBounds();
    totalBounds.extend(polyBounds.getNorthEast());
    totalBounds.extend(polyBounds.getSouthWest());
  }
  
  // hit test the corners (method 2)
  var hitTestTL = ge.getView().hitTest(0, ge.UNITS_FRACTION, 0, ge.UNITS_FRACTION, ge.HIT_TEST_GLOBE);
  var hitTestTR = ge.getView().hitTest(1, ge.UNITS_FRACTION, 0, ge.UNITS_FRACTION, ge.HIT_TEST_GLOBE);
  var hitTestBR = ge.getView().hitTest(1, ge.UNITS_FRACTION, 1, ge.UNITS_FRACTION, ge.HIT_TEST_GLOBE);
  var hitTestBL = ge.getView().hitTest(0, ge.UNITS_FRACTION, 1, ge.UNITS_FRACTION, ge.HIT_TEST_GLOBE);
  
  // ensure that all hit tests succeeded (i.e. the viewport is 2d-mappable)
  if (hitTestTL &amp;&amp; hitTestTR &amp;&amp; hitTestBL &amp;&amp; hitTestBR) {
    var hitTestBoundsPolygon = new GPolygon([
        new GLatLng(hitTestTL.getLatitude(), hitTestTL.getLongitude()),
        new GLatLng(hitTestTR.getLatitude(), hitTestTR.getLongitude()),
        new GLatLng(hitTestBR.getLatitude(), hitTestBR.getLongitude()),
        new GLatLng(hitTestBL.getLatitude(), hitTestBL.getLongitude()),
        new GLatLng(hitTestTL.getLatitude(), hitTestTL.getLongitude())],
        '#ff0000', 2, 1.00,
        '#ff0000',    0.25,
        { clickable: false });
    map.addOverlay(hitTestBoundsPolygon);

    var polyBounds = hitTestBoundsPolygon.getBounds();
    totalBounds.extend(polyBounds.getNorthEast());
    totalBounds.extend(polyBounds.getSouthWest());
  }
  
  if (!totalBounds.isEmpty()) {
    map.setCenter(fakeBoundsCenter ? fakeBoundsCenter : totalBounds.getCenter(),
        map.getBoundsZoomLevel(totalBounds));
  }
});</pre>    </div>
  </div>
</body>
</html>
